#include "common.cuh"

__global__ void testGPU() { printf("GPU test from thread %d\n", threadIdx.x); }

void setGPU() {
    int iDeviceCount;

    errorCheck(cudaGetDeviceCount(&iDeviceCount), __FILE__, __LINE__);
    if (iDeviceCount == 0) {
        printf("No CUDA devices found\n");
        exit(-1);
    }

    int iDev = 0;
    errorCheck(cudaSetDevice(iDev), __FILE__, __LINE__);

    testGPU<<<1, 2>>>();
}

void cudaDeviceCheck() {
    cudaDeviceProp prop;
    errorCheck(cudaGetDeviceProperties(&prop, 0), __FILE__, __LINE__);
    printf("Device name: %s\n", prop.name);
    printf("  Total global memory:          %zu GB\n",
           prop.totalGlobalMem / (1024 * 1024 * 1024));
    printf("  Shared memory per block:      %zu bytes\n", prop.sharedMemPerBlock);
    printf("  Registers per block:          %d\n", prop.regsPerBlock);
    printf("  Warp size:                    %d\n", prop.warpSize);
    printf("  Max threads per block:        %d\n", prop.maxThreadsPerBlock);
    printf("  Max threads dimensions:       %d x %d x %d\n", prop.maxThreadsDim[0],
           prop.maxThreadsDim[1], prop.maxThreadsDim[2]);
    printf("  Max grid size:                %d x %d x %d\n", prop.maxGridSize[0],
           prop.maxGridSize[1], prop.maxGridSize[2]);
    printf("  Total constant memory:        %zu bytes\n",
           prop.totalConstMem / (1024 * 1024 * 1024));
}

cudaError_t errorCheck(cudaError_t err, const char *filename, int line) {
    if (err != cudaSuccess) {
        printf("CUDA Error: %s at %s:%d\n", cudaGetErrorString(err), filename,
               line);
        return err;
    }
    return err;
}